<?xml version="1.0" encoding="UTF-8"?>
<xsl:transform version="1.0"
	xmlns:exsl="http://exslt.org/common"
	xmlns:set="http://exslt.org/sets"
	xmlns:str="http://exslt.org/strings"
	exclude-result-prefixes="set str"
	extension-element-prefixes="exsl"
	xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

	<!-- Zwei Arten der Visualisierung werden hier implementiert:
	erstens als XML (mode="xml"); und
	zweitens als Kastenverschachtelung (mode="dump"). -->

	<!-- *** *** *** Modus: xml (xml-impl, xml-ns)*** *** *** -->

	<!-- Bekannter Fehler: Ein Ampersand in der HTML-Ausgabe wird nicht als
	doppelte Entitätsreferenz visualisiert. Damit könnte man das XML vom
	Browser-Fenster kopieren und weiter verarbeiten. In 1.0 ist das aber
	wohl zu schwer. -->

	<xsl:template match="*" mode="xml"><!-- mit Element beginnen -->
		<div class="xd">
			<xsl:apply-templates select="." mode="xml-impl">
				<xsl:with-param name="ns-decl" select="true()"/>
			</xsl:apply-templates>
		</div>
	</xsl:template><!-- hierunter die Implementierung -->

	<xsl:template match="*[node()]" mode="xml-impl"><!-- mit Kindern -->
		<xsl:param name="level" select="0"/>
		<xsl:param name="ns-decl" select="false()"/>
		<!-- Element öffnen -->
		<span class="xd-elm" style="margin-left: {$level}em;" >
			&lt;<span class="xd-elmn"><xsl:value-of select="name()"/></span>
			<span class="xd-attr"><!-- Attribute -->
				<xsl:if test="$ns-decl"><xsl:call-template name="nsdecl"/></xsl:if>
				<xsl:apply-templates select="@*" mode="xml-impl"/>
			</span>&gt;
		</span>
		<xsl:apply-templates select="." mode="xml-br"/><!-- Kinder -->
		<xsl:apply-templates select="node()" mode="xml-impl">
			<xsl:with-param name="level" select="$level + 1"/>
		</xsl:apply-templates>
		<span class="xd-elm" ><!-- Element schließen -->
			<!-- Was Kinder enthält, die kein Text sind, wird eingerückt. -->
			<xsl:apply-templates select="." mode="xml-ind">
				<xsl:with-param name="level" select="$level"/>
			</xsl:apply-templates>
			&lt;/<span class="xd-elmn"><xsl:value-of select="name()"/></span>&gt;
		</span><br/>
	</xsl:template>

	<xsl:template match="*" mode="xml-impl"><!-- ohne Kinder -->
		<xsl:param name="level" select="0"/>
		<xsl:param name="ns-decl" select="false()"/>
		<span class="xd-elm" style="margin-left: {$level}em;" ><!-- öffnen -->
			&lt;<span class="xd-elmn"><xsl:value-of select="name()"/></span>
		<span class="xd-attr"><!-- Attribute -->
			<xsl:if test="$ns-decl"><xsl:call-template name="nsdecl"/></xsl:if>
			<xsl:apply-templates select="@*" mode="xml-impl"/>
		</span>
		/&gt;</span><br/><!-- geschlossen -->
	</xsl:template>

	<!-- Namensräume sammeln und deklarieren -->
	<xsl:template name="nsdecl">
		<xsl:variable name="nsp-rtf">
			<xsl:for-each select=".//* | .//@*"><ns>
					<used/><!-- tatsächlich benutzter Namensrarum -->
					<pre><xsl:value-of select="substring-before( name(), ':')"/></pre>
					<xsl:text>|</xsl:text><!-- Trenner -->
					<uri><xsl:value-of select="namespace-uri()"/></uri>
			</ns></xsl:for-each>
			<xsl:for-each select="namespace::node()"><!-- nur deklariert --><ns>
					<pre><xsl:value-of select="name()"/></pre>
					<xsl:text>|</xsl:text><!-- Trenner -->
					<uri><xsl:value-of select="."/></uri>
			</ns></xsl:for-each>
		</xsl:variable>
		<span class="xd-ns">
			<xsl:for-each select="set:distinct( exsl:node-set($nsp-rtf)/ns )">
				<xsl:apply-templates select="." mode="xml-ns"/>
			</xsl:for-each>
		</span>
	</xsl:template>

	<xsl:template match="@*" mode="xml-impl"><!-- Attribute -->
		<xsl:value-of select="concat( ' ', name(), '=&quot;')"/>
		<em><xsl:value-of select="."/></em>
		<xsl:text>&quot;</xsl:text>
	</xsl:template>

	<xsl:template match="text()" mode="xml-impl"><!-- Text -->
		<em><xsl:value-of select="."/></em>
	</xsl:template>

	<xsl:template match="*" mode="xml-br"><!-- neue Zeile -->
		<xsl:choose>
			<xsl:when test="count(node()) = count(text())"></xsl:when>
			<xsl:otherwise><br/></xsl:otherwise>
		</xsl:choose>
	</xsl:template>

	<xsl:template match="*" mode="xml-ind"><!-- Einrückung -->
		<xsl:param name="level"/>
		<xsl:if test="count(node()) != count(text())">
			<xsl:attribute name="style">margin-left: <xsl:value-of
					select="concat( $level, 'em;')"/></xsl:attribute> 
		</xsl:if>
	</xsl:template>

	<!-- XML-Namensraum und Leer-Namensraum nicht ausgeben -->
	<xsl:template mode="xml-ns" priority="1" match="
		ns[ uri = 'http://www.w3.org/XML/1998/namespace' ] |
		ns[ string-length(pre) = 0 and string-length(uri) = 0 ]"/>
	<!-- Störfaktoren auch nicht ausgeben :-) -->
	<xsl:template mode="xml-ns" priority="1" match="used | text()"/>

	<xsl:template match="ns" mode="xml-ns">
		<xsl:apply-templates mode="xml-ns"/>
	</xsl:template>

	<xsl:template match="ns/pre" mode="xml-ns"> xmlns<xsl:if
			test="string-length()">
			<xsl:value-of select="concat(':', .)"/></xsl:if>=</xsl:template>

	<xsl:template match="ns[used]/uri" mode="xml-ns" priority="1">
		<xsl:text/>"<span class="xd-ns-used">
			<xsl:value-of select="."/></span>"</xsl:template>
	<!-- nur deklarierte, aber nicht genutzte Namensräume anders darstellen -->
	<xsl:template match="ns/uri" mode="xml-ns">"<span class="xd-ns-decl">
			<xsl:value-of select="."/></span>"</xsl:template>

	<!-- *** *** *** dump *** *** *** -->

	<xsl:template match="*" mode="dump">
		<xsl:param name="level" select="1"/>
		<xsl:if test="*">
			<div class="clearer">&#160;</div>
		</xsl:if>
		<xsl:variable name="str">
			<xsl:if test="text() and normalize-space()">
				<xsl:value-of select="normalize-space(str:concat(text()))"/>
			</xsl:if>
		</xsl:variable>
		<div class="dump">
			<xsl:if test="string-length($str)">
				<xsl:attribute name="title">
					<xsl:value-of select="$str"/>
				</xsl:attribute>
			</xsl:if>
			<p>
				<xsl:choose>
					<xsl:when test="namespace-uri() = 'http://as-guides.com/wev1'">
						<xsl:text>a:</xsl:text>
					</xsl:when>
					<xsl:otherwise>
						<xsl:value-of select="concat('{', namespace-uri(), '}')"/>
					</xsl:otherwise>
				</xsl:choose>
				<xsl:value-of select="local-name()"/>
			</p>
			<xsl:if test="string-length($str)">
				<xsl:text> </xsl:text>
				<p>
					<xsl:value-of select="concat('[', string-length($str), ']')"/>
				</p>
			</xsl:if>
			<xsl:for-each select="@*">
				<span>
					<xsl:attribute name="title">
						<xsl:value-of select="."/>
					</xsl:attribute>
					<xsl:value-of select="concat(' @', local-name())"/>
				</span>
			</xsl:for-each>
			<xsl:apply-templates mode="dump" select="*">
				<xsl:with-param name="level" select="$level + 1"/>
			</xsl:apply-templates>
		</div>
		<xsl:if test="*">
			<div class="clearer">&#160;</div>
		</xsl:if>
	</xsl:template>

	<xsl:param name="var-dump"/>

	<xsl:template name="var-dump">
		<xsl:if test="$var-dump">
			<pre class="debug"><xsl:value-of select="$var-dump"/></pre>
		</xsl:if>
	</xsl:template>

	<xsl:param name="dump-session"/>

	<xsl:template name="dump-session">
		<xsl:if test="$dump-session">
			<pre class="debug"><xsl:value-of select="$dump-session"/></pre>
		</xsl:if>
	</xsl:template>

	<xsl:param name="dump1"/>
	<xsl:param name="dump2"/>

	<xsl:template name="dump-side-by-side">
		<xsl:if test="$dump1 and $dump2">
			<div class="debug">
				<div style="float:left; width:300px;">
					<pre><xsl:value-of select="$dump1"/></pre>
				</div>
				<div style="float:left; width:300px;">
					<pre><xsl:value-of select="$dump2"/></pre>
				</div>
				<div class="clearer"/>
			</div>
		</xsl:if>
	</xsl:template>

</xsl:transform>
